import { PrismaClient } from '@prisma/client';

// 小分类定义接口
interface SubCategory {
  key: string;
  name: string;
  markets?: string[];
  codePattern?: RegExp;
  description?: string;
}

// 大分类定义接口
interface MainCategory {
  key: string;
  name: string;
  description?: string;
  subCategories: SubCategory[];
}

// 大分类和小分类的层级结构
const CATEGORY_HIERARCHY: MainCategory[] = [
  {
    key: 'a_stock',
    name: 'A股市场',
    description: '中国内地A股市场',
    subCategories: [
      {
        key: 'sh_a',
        name: '上证A股',
        markets: ['SH'],
        codePattern: /^6/,
        description: '上海证券交易所A股（代码以6开头）'
      },
      {
        key: 'sz_a',
        name: '深证A股',
        markets: ['SZ'],
        codePattern: /^00/,
        description: '深圳证券交易所主板A股（代码以00开头）'
      },
      {
        key: 'cy',
        name: '创业板',
        markets: ['SZ'],
        codePattern: /^3/,
        description: '创业板股票（代码以3开头）'
      },
      {
        key: 'kc',
        name: '科创板',
        markets: ['SH'],
        codePattern: /^688/,
        description: '科创板股票（代码以688开头）'
      },
      {
        key: 'bj',
        name: '北交所',
        markets: ['NEEQ'],
        codePattern: /^[48]/,
        description: '北京证券交易所（代码以4、8开头）'
      }
    ]
  },
  {
    key: 'hk_stock',
    name: '香港市场',
    description: '香港交易所股票市场',
    subCategories: [
      {
        key: 'hk_main',
        name: '港股主板',
        markets: ['HK'],
        codePattern: /^[0-9]{5}$/,
        description: '香港主板股票'
      },
      {
        key: 'hk_gem',
        name: '香港创业板',
        markets: ['HK'],
        codePattern: /^8/,
        description: '香港创业板股票（代码以8开头）'
      }
    ]
  },
  {
    key: 'us_stock',
    name: '美股市场',
    description: '美国股票市场',
    subCategories: [
      {
        key: 'nasdaq',
        name: '纳斯达克',
        markets: ['US'],
        description: '纳斯达克交易所股票'
      },
      {
        key: 'nyse',
        name: '纽约证交所',
        markets: ['US'],
        description: '纽约证券交易所股票'
      }
    ]
  },
  {
    key: 'uk_stock',
    name: '英股市场',
    description: '英国股票市场',
    subCategories: [
      {
        key: 'lse',
        name: '伦敦证交所',
        markets: ['UK'],
        description: '伦敦证券交易所股票'
      }
    ]
  }
];

export class StockCategoryService {
  private prisma: PrismaClient;

  constructor() {
    this.prisma = new PrismaClient();
  }

  /**
   * 获取所有大分类
   */
  async getMainCategories() {
    return {
      categories: CATEGORY_HIERARCHY.map(mainCat => ({
        key: mainCat.key,
        name: mainCat.name,
        description: mainCat.description,
        subCategoryCount: mainCat.subCategories.length
      }))
    };
  }

  /**
   * 根据大分类获取小分类列表
   */
  async getSubCategories(mainCategoryKey: string) {
    const mainCategory = CATEGORY_HIERARCHY.find(cat => cat.key === mainCategoryKey);
    
    if (!mainCategory) {
      throw new Error(`未找到大分类: ${mainCategoryKey}`);
    }

    return {
      mainCategory: {
        key: mainCategory.key,
        name: mainCategory.name,
        description: mainCategory.description
      },
      subCategories: mainCategory.subCategories.map(subCat => ({
        key: subCat.key,
        name: subCat.name,
        description: subCat.description
      }))
    };
  }

  /**
   * 根据大分类获取所有股票列表
   * @param mainCategoryKey 大分类键值
   * @param pageIndex 页码（从1开始）
   * @param pageSize 每页条数
   */
  async getStocksByMainCategory(mainCategoryKey: string, pageIndex: number = 1, pageSize: number = 20) {
    // 查找大分类定义
    const mainCategory = CATEGORY_HIERARCHY.find(cat => cat.key === mainCategoryKey);
    
    if (!mainCategory) {
      throw new Error(`未找到大分类: ${mainCategoryKey}`);
    }

    // 收集所有小分类的股票
    const allStocks = [];
    
    for (const subCategory of mainCategory.subCategories) {
      // 构建查询条件
      const whereClause: any = { status: 1 };
      
      // 市场过滤
      if (subCategory.markets && subCategory.markets.length > 0) {
        const marketIds = await this.getMarketIds(subCategory.markets);
        whereClause.marketId = { in: marketIds };
      }

      // 股票代码规则过滤
      if (subCategory.codePattern) {
        // 先获取符合市场条件的所有股票
        const categoryStocks = await this.prisma.stock.findMany({
          where: {
            marketId: whereClause.marketId,
            status: 1
          },
          include: {
            market: true,
            realtime: true
          }
        });

        // 在应用层应用正则过滤
        const filteredStocks = categoryStocks.filter(stock => 
          subCategory.codePattern!.test(stock.stockCode)
        );
        
        allStocks.push(...filteredStocks);
      } else {
        // 普通查询（无代码规则）
        const categoryStocks = await this.prisma.stock.findMany({
          where: whereClause,
          include: {
            market: true,
            realtime: true
          }
        });
        
        allStocks.push(...categoryStocks);
      }
    }

    // 手动分页
    const skip = (pageIndex - 1) * pageSize;
    const paginatedStocks = allStocks.slice(skip, skip + pageSize);

    return {
      data: paginatedStocks.map(this.formatStock),
      pagination: {
        pageIndex,
        pageSize,
        total: allStocks.length,
        totalPages: Math.ceil(allStocks.length / pageSize)
      },
      categoryInfo: {
        mainCategory: mainCategoryKey,
        name: mainCategory.name,
        description: mainCategory.description,
        subCategoryCount: mainCategory.subCategories.length
      }
    };
  }

  /**
   * 根据小分类获取股票列表
   * @param subCategoryKey 小分类键值
   * @param pageIndex 页码（从1开始）
   * @param pageSize 每页条数
   */
  async getStocksBySubCategory(subCategoryKey: string, pageIndex: number = 1, pageSize: number = 20) {
    // 查找小分类定义
    let subCategory: SubCategory | null = null;
    let mainCategoryKey = '';
    
    for (const mainCat of CATEGORY_HIERARCHY) {
      const foundSubCat = mainCat.subCategories.find(sub => sub.key === subCategoryKey);
      if (foundSubCat) {
        subCategory = foundSubCat;
        mainCategoryKey = mainCat.key;
        break;
      }
    }
    
    if (!subCategory) {
      throw new Error(`未找到小分类: ${subCategoryKey}`);
    }

    // 构建查询条件
    const whereClause: any = { status: 1 };
    
    // 市场过滤
    if (subCategory.markets && subCategory.markets.length > 0) {
      const marketIds = await this.getMarketIds(subCategory.markets);
      whereClause.marketId = { in: marketIds };
    }

    // 股票代码规则过滤
    if (subCategory.codePattern) {
      // 先获取符合市场条件的所有股票
      const allStocks = await this.prisma.stock.findMany({
        where: {
          marketId: whereClause.marketId,
          status: 1
        },
        include: {
          market: true,
          realtime: true
        }
      });

      // 在应用层应用正则过滤
      const filteredStocks = allStocks.filter(stock => 
        subCategory.codePattern!.test(stock.stockCode)
      );

      // 手动分页
      const skip = (pageIndex - 1) * pageSize;
      const paginatedStocks = filteredStocks.slice(skip, skip + pageSize);

      return {
        data: paginatedStocks.map(this.formatStock),
        pagination: {
          pageIndex,
          pageSize,
          total: filteredStocks.length,
          totalPages: Math.ceil(filteredStocks.length / pageSize)
        },
        categoryInfo: {
          mainCategory: mainCategoryKey,
          subCategory: subCategoryKey,
          name: subCategory.name
        }
      };
    }

    // 普通查询（无代码规则）
    const skip = (pageIndex - 1) * pageSize;
    
    const [stocks, total] = await Promise.all([
      this.prisma.stock.findMany({
        where: whereClause,
        include: {
          market: true,
          realtime: true
        },
        skip,
        take: pageSize,
        orderBy: { updatedAt: 'desc' }
      }),
      this.prisma.stock.count({ where: whereClause })
    ]);

    return {
      data: stocks.map(this.formatStock),
      pagination: {
        pageIndex,
        pageSize,
        total,
        totalPages: Math.ceil(total / pageSize)
      },
      categoryInfo: {
        mainCategory: mainCategoryKey,
        subCategory: subCategoryKey,
        name: subCategory.name
      }
    };
  }

  /**
   * 获取大分类统计信息
   */
  async getMainCategoryStats() {
    const stats = [];
    
    for (const mainCategory of CATEGORY_HIERARCHY) {
      let totalCount = 0;
      const subCategoryStats = [];
      
      for (const subCategory of mainCategory.subCategories) {
        let count = 0;
        
        if (subCategory.markets && subCategory.markets.length > 0) {
          const marketIds = await this.getMarketIds(subCategory.markets);
          
          if (subCategory.codePattern) {
            // 需要应用层过滤的分类
            const stocks = await this.prisma.stock.findMany({
              where: {
                marketId: { in: marketIds },
                status: 1
              },
              select: { stockCode: true }
            });
            
            count = stocks.filter(stock => 
              subCategory.codePattern!.test(stock.stockCode)
            ).length;
          } else {
            // 直接数据库查询的分类
            count = await this.prisma.stock.count({
              where: {
                marketId: { in: marketIds },
                status: 1
              }
            });
          }
        }
        
        subCategoryStats.push({
          key: subCategory.key,
          name: subCategory.name,
          stockCount: count
        });
        
        totalCount += count;
      }
      
      stats.push({
        key: mainCategory.key,
        name: mainCategory.name,
        totalStockCount: totalCount,
        subCategories: subCategoryStats
      });
    }
    
    return stats;
  }

  /**
   * 获取指定小分类的统计信息
   */
  async getSubCategoryStats(subCategoryKey: string) {
    // 查找小分类定义
    let subCategory: SubCategory | null = null;
    let mainCategoryInfo = null;
    
    for (const mainCat of CATEGORY_HIERARCHY) {
      const foundSubCat = mainCat.subCategories.find(sub => sub.key === subCategoryKey);
      if (foundSubCat) {
        subCategory = foundSubCat;
        mainCategoryInfo = { key: mainCat.key, name: mainCat.name };
        break;
      }
    }
    
    if (!subCategory) {
      throw new Error(`未找到小分类: ${subCategoryKey}`);
    }

    let count = 0;
    
    if (subCategory.markets && subCategory.markets.length > 0) {
      const marketIds = await this.getMarketIds(subCategory.markets);
      
      if (subCategory.codePattern) {
        const stocks = await this.prisma.stock.findMany({
          where: {
            marketId: { in: marketIds },
            status: 1
          },
          select: { stockCode: true }
        });
        
        count = stocks.filter(stock => 
          subCategory.codePattern!.test(stock.stockCode)
        ).length;
      } else {
        count = await this.prisma.stock.count({
          where: {
            marketId: { in: marketIds },
            status: 1
          }
        });
      }
    }
    
    return {
      mainCategory: mainCategoryInfo,
      subCategory: {
        key: subCategory.key,
        name: subCategory.name,
        description: subCategory.description,
        stockCount: count
      }
    };
  }

  /**
   * 根据市场代码获取市场ID
   */
  private async getMarketIds(marketCodes: string[]): Promise<number[]> {
    const markets = await this.prisma.market.findMany({
      where: {
        marketCode: { in: marketCodes }
      },
      select: { id: true }
    });
    
    return markets.map(market => market.id);
  }

  /**
   * 获取大分类市场概览
   */
  async getMainCategoryOverview() {
    const overview = [];
    
    for (const mainCategory of CATEGORY_HIERARCHY) {
      let totalStocks = 0;
      let activeStocks = 0;
      let avgChangePercent = 0;
      const subCategoryOverview = [];
      
      for (const subCategory of mainCategory.subCategories) {
        if (subCategory.markets && subCategory.markets.length > 0) {
          const marketIds = await this.getMarketIds(subCategory.markets);
          
          // 获取小分类股票数量和实时数据统计
          let subCategoryStocks = [];
          if (subCategory.codePattern) {
            const allStocks = await this.prisma.stock.findMany({
              where: {
                marketId: { in: marketIds },
                status: 1
              },
              include: { realtime: true }
            });
            subCategoryStocks = allStocks.filter(stock => 
              subCategory.codePattern!.test(stock.stockCode)
            );
          } else {
            subCategoryStocks = await this.prisma.stock.findMany({
              where: {
                marketId: { in: marketIds },
                status: 1
              },
              include: { realtime: true }
            });
          }
          
          const stocksWithRealtime = subCategoryStocks.filter(stock => stock.realtime);
          const subCategoryAvgChange = stocksWithRealtime.length > 0 
            ? stocksWithRealtime.reduce((sum, stock) => 
                sum + (stock.realtime?.changePercent ? parseFloat(stock.realtime.changePercent.toString()) : 0), 0
              ) / stocksWithRealtime.length
            : 0;
          
          subCategoryOverview.push({
            key: subCategory.key,
            name: subCategory.name,
            totalStocks: subCategoryStocks.length,
            activeStocks: stocksWithRealtime.length,
            avgChangePercent: Math.round(subCategoryAvgChange * 100) / 100
          });
          
          totalStocks += subCategoryStocks.length;
          activeStocks += stocksWithRealtime.length;
          avgChangePercent += subCategoryAvgChange * subCategoryStocks.length;
        }
      }
      
      avgChangePercent = totalStocks > 0 ? avgChangePercent / totalStocks : 0;
      
      overview.push({
        key: mainCategory.key,
        name: mainCategory.name,
        description: mainCategory.description,
        totalStocks,
        activeStocks,
        avgChangePercent: Math.round(avgChangePercent * 100) / 100,
        subCategories: subCategoryOverview
      });
    }
    
    return overview;
  }

  /**
   * 获取大分类评分
   */
  async getMainCategoryRating(mainCategoryKey?: string) {
    // 如果没有指定大分类，默认使用A股市场
    const targetMainCategory = mainCategoryKey || 'a_stock';
    const mainCategory = CATEGORY_HIERARCHY.find(cat => cat.key === targetMainCategory);

    if (!mainCategory) {
      throw new Error(`找不到${targetMainCategory}大分类数据`);
    }

    // 获取该大分类下所有股票的实时数据
    const allRealtimeData = [];
    
    for (const subCategory of mainCategory.subCategories) {
      if (subCategory.markets && subCategory.markets.length > 0) {
        const marketIds = await this.getMarketIds(subCategory.markets);
        
        let subCategoryStocks = [];
        if (subCategory.codePattern) {
          const allStocks = await this.prisma.stock.findMany({
            where: {
              marketId: { in: marketIds },
              status: 1
            },
            include: { realtime: true }
          });
          subCategoryStocks = allStocks.filter(stock => 
            subCategory.codePattern!.test(stock.stockCode) && stock.realtime
          );
        } else {
          subCategoryStocks = await this.prisma.stock.findMany({
            where: {
              marketId: { in: marketIds },
              status: 1,
              realtime: { isNot: null }
            },
            include: { realtime: true }
          });
        }
        
        allRealtimeData.push(...subCategoryStocks.map(stock => stock.realtime));
      }
    }

    if (allRealtimeData.length === 0) {
      return { 
        rating: 5, 
        description: '暂无数据',
        mainCategory: {
          key: mainCategory.key,
          name: mainCategory.name
        }
      };
    }

    // 计算涨跌统计
    const riseCount = allRealtimeData.filter(item => 
      item?.changePercent && parseFloat(item.changePercent.toString()) > 0
    ).length;
    const fallCount = allRealtimeData.filter(item => 
      item?.changePercent && parseFloat(item.changePercent.toString()) < 0
    ).length;
    const flatCount = allRealtimeData.filter(item => 
      !item?.changePercent || parseFloat(item.changePercent.toString()) === 0
    ).length;

    // 计算平均涨跌幅
    const avgChange = allRealtimeData.reduce((sum, item) => {
      return sum + (item?.changePercent ? parseFloat(item.changePercent.toString()) : 0);
    }, 0) / allRealtimeData.length;

    // 基于涨跌比例和平均涨跌幅计算评分
    const riseRatio = riseCount / allRealtimeData.length;
    let rating = 5; // 默认中性评分

    if (avgChange > 2) {
      rating = 9; // 大涨
    } else if (avgChange > 1) {
      rating = 8; // 上涨
    } else if (avgChange > 0.5) {
      rating = 7; // 微涨
    } else if (avgChange > -0.5) {
      rating = 5; // 平稳
    } else if (avgChange > -1) {
      rating = 4; // 微跌
    } else if (avgChange > -2) {
      rating = 3; // 下跌
    } else {
      rating = 2; // 大跌
    }

    // 根据上涨股票比例调整评分
    if (riseRatio > 0.7) {
      rating = Math.min(10, rating + 1);
    } else if (riseRatio < 0.3) {
      rating = Math.max(1, rating - 1);
    }

    const descriptions = {
      1: '极度悲观', 2: '非常悲观', 3: '悲观', 4: '偏悲观', 5: '中性',
      6: '偏乐观', 7: '乐观', 8: '非常乐观', 9: '极度乐观', 10: '狂欢'
    };

    return {
      rating: Math.round(rating),
      description: descriptions[Math.round(rating) as keyof typeof descriptions] || '中性',
      mainCategory: {
        key: mainCategory.key,
        name: mainCategory.name
      },
      statistics: {
        totalStocks: allRealtimeData.length,
        riseCount,
        fallCount,
        flatCount,
        riseRatio: Math.round(riseRatio * 10000) / 100, // 百分比保留2位小数
        avgChange: Math.round(avgChange * 100) / 100
      }
    };
  }

  /**
   * 获取大分类涨跌分布统计
   */
  async getMainCategoryRiseFallDistribution(mainCategoryKey?: string) {
    // 如果没有指定大分类，默认使用A股市场
    const targetMainCategory = mainCategoryKey || 'a_stock';
    const mainCategory = CATEGORY_HIERARCHY.find(cat => cat.key === targetMainCategory);

    if (!mainCategory) {
      throw new Error(`找不到${targetMainCategory}大分类数据`);
    }

    // 获取该大分类下所有股票的实时数据
    const allRealtimeData = [];
    
    for (const subCategory of mainCategory.subCategories) {
      if (subCategory.markets && subCategory.markets.length > 0) {
        const marketIds = await this.getMarketIds(subCategory.markets);
        
        let subCategoryStocks = [];
        if (subCategory.codePattern) {
          const allStocks = await this.prisma.stock.findMany({
            where: {
              marketId: { in: marketIds },
              status: 1
            },
            include: { realtime: true }
          });
          subCategoryStocks = allStocks.filter(stock => 
            subCategory.codePattern!.test(stock.stockCode) && stock.realtime
          );
        } else {
          subCategoryStocks = await this.prisma.stock.findMany({
            where: {
              marketId: { in: marketIds },
              status: 1,
              realtime: { isNot: null }
            },
            include: { realtime: true }
          });
        }
        
        allRealtimeData.push(...subCategoryStocks.map(stock => stock.realtime));
      }
    }

    // 涨跌停统计
    const limitUp = allRealtimeData.filter(item => 
      item?.changePercent && parseFloat(item.changePercent.toString()) >= 9.8
    ).length;
    
    const limitDown = allRealtimeData.filter(item => 
      item?.changePercent && parseFloat(item.changePercent.toString()) <= -9.8
    ).length;

    // 涨跌幅区间统计
    const ranges = {
      'rise_over_5': 0,    // 涨超5%
      'rise_3_to_5': 0,    // 涨3%-5%
      'rise_1_to_3': 0,    // 涨1%-3%
      'rise_0_to_1': 0,    // 涨0%-1%
      'fall_0_to_1': 0,    // 跌0%-1%
      'fall_1_to_3': 0,    // 跌1%-3%
      'fall_3_to_5': 0,    // 跌3%-5%
      'fall_over_5': 0     // 跌超5%
    };

    allRealtimeData.forEach(item => {
      const change = item?.changePercent ? parseFloat(item.changePercent.toString()) : 0;
      
      if (change > 5) {
        ranges.rise_over_5++;
      } else if (change > 3) {
        ranges.rise_3_to_5++;
      } else if (change > 1) {
        ranges.rise_1_to_3++;
      } else if (change > 0) {
        ranges.rise_0_to_1++;
      } else if (change > -1) {
        ranges.fall_0_to_1++;
      } else if (change > -3) {
        ranges.fall_1_to_3++;
      } else if (change > -5) {
        ranges.fall_3_to_5++;
      } else {
        ranges.fall_over_5++;
      }
    });

    // 获取昨日涨停今日跟跌的股票数量（简化估算）
    const yesterdayLimitUpTodayFall = Math.floor(limitUp * 0.2);

    return {
      mainCategory: {
        key: mainCategory.key,
        name: mainCategory.name
      },
      limitUp,
      limitDown,
      yesterdayLimitUpTodayFall,
      distribution: ranges,
      totalStocks: allRealtimeData.length,
      timestamp: new Date()
    };
  }

  /**
   * 格式化股票数据
   */
  private formatStock(stock: any) {
    return {
      ...stock,
      totalShares: stock.totalShares ? stock.totalShares.toString() : null,
      outstandingShares: stock.outstandingShares ? stock.outstandingShares.toString() : null,
      realtime: stock.realtime ? {
        ...stock.realtime,
        volume: stock.realtime.volume ? stock.realtime.volume.toString() : null
      } : null
    };
  }
}